/**
 * LeetCode 62. 不同路径
 */
public class Solution_62 {
    /**
     * 方法二：组合数学
     * <p>
     * 从左上角到右下角，需要向下移动 m-1 次，向右移动 n-1 次，共 m+n-2 次。
     * <p>
     * 因此路径总数就等于从 m+n-2 次移动中选择 m-1 次向下移动，即 C(m+n−2, m−1)
     * <p>
     * [(m+n−2)*(m+n−3)*...*n] / [(m-1)!]
     * <p>
     * 时间复杂度：O(min(m,n))
     * <p>
     * 空间复杂度：O(1)
     */
    public int uniquePaths(int m, int n) {
        long ans = 1;
        for (int x = n, y = 1; y < m; x++, y++) {
            ans = ans * x / y;
        }
        return (int) ans;
    }

    /**
     * 方法一：动态规划
     * <p>
     * 时间复杂度：O(mn)
     * <p>
     * 空间复杂度：O(mn)
     */
    public int uniquePaths1(int m, int n) {
        int[][] dp = new int[m][n];
        for (int i = 0; i < m; i++) {
            dp[i][0] = 1;
        }
        for (int j = 0; j < n; j++) {
            dp[0][j] = 1;
        }
        for (int i = 1; i < m; i++) {
            for (int j = 1; j < n; j++) {
                dp[i][j] = dp[i][j - 1] + dp[i - 1][j];
            }
        }
        return dp[m - 1][n - 1];
    }
}
